package com.cmcc.example.face.noSdk.controller;

import com.alibaba.fastjson.JSON;
import com.cmcc.example.face.common.vo.ResultVO;
import com.cmcc.example.face.noSdk.common.vo.response.EcloudBaseResponseVO;
import com.cmcc.example.face.noSdk.service.FaceService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * <name>FaceSetController</name>
 * 人脸集合管理相关接口
 * </p >
 *
 * @author arabira
 * @version 1.0 2020-04-13
 * @since 1.0
 */
@Slf4j
@RestController
@RequestMapping("/nosdk/faceset")
public class FaceSetController {
    @Autowired
    private FaceService faceService;

    /**
     * 添加人脸集合
     * @param request
     * @return
     */
    @RequestMapping(value = "/info", method = RequestMethod.POST)
    public ResultVO addFaceSet(@RequestBody Map<String, Object> request) {
        if (request.containsKey("faceSetName")) {
            String faceSetName = String.valueOf(request.get("faceSetName"));
            String description = request.get("description") == null ? "" : String.valueOf(request.get("description"));
            EcloudBaseResponseVO responseVO = faceService.createFaceSet(faceSetName, description);
            return responseToFront(responseVO);
        }
        else {
            return ResultVO.note(HttpStatus.FORBIDDEN.value(), "", "添加的人脸集合名词不为空");
        }
    }

    /**
     * 查找人脸集合
     * @param request
     * @return
     */
    @RequestMapping(value = "/info/list", method = RequestMethod.POST)
    public ResultVO findFaceSet(@RequestBody Map request) {
        String faceSetName = request.containsKey("faceSetName") ? String.valueOf(request.get("faceSetName")) : null;
        Integer pageNum = request.containsKey("pageNum") ? Integer.parseInt(String.valueOf(request.get("pageNum"))) : null;
        Integer pageSize = request.containsKey("pageSize") ? Integer.parseInt(String.valueOf(request.get("pageSize"))) : null;
        EcloudBaseResponseVO responseVO = faceService.findFaceSet(faceSetName, pageNum, pageSize);
        return responseToFront(responseVO);
    }

    /**
     * 删除人脸集合
     * @param request
     * @return
     */
    @RequestMapping(value = "/info", method = RequestMethod.DELETE)
    public ResultVO deleteFaceSet(@RequestBody Map<String, List<Integer>> request) {
        if (request.containsKey("faceSetIds") ) {
            List<Integer> ids = request.get("faceSetIds");
            List<String> idsString = ids.stream().map(value -> String.valueOf(value)).collect(Collectors.toList());
            EcloudBaseResponseVO responseVO = faceService.deleteFaceSet(idsString);
            return responseToFront(responseVO);
        }
        else {
            return ResultVO.note(HttpStatus.FORBIDDEN.value(), "", "id列表不可为空");
        }
    }

    /**
     * 添加人脸到集合
     * @param userName
     * @param faceSetId
     * @param image
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/user/face/info", method = RequestMethod.POST)
    public ResultVO addFaceToSet(@RequestParam("userName") String userName, @RequestParam("faceSetId") String faceSetId, @RequestParam("img")MultipartFile image) throws IOException {
        if (StringUtils.isNotBlank(userName) &&  NumberUtils.isDigits(faceSetId)) {
            EcloudBaseResponseVO responseVO = faceService.addFaceMessageToFaceSet(userName, Integer.parseInt(faceSetId), image);
            return responseToFront(responseVO);
        }
        else {
            return ResultVO.note(HttpStatus.FORBIDDEN.value(), "", "用户名称或人脸集合id类型错误");
        }
    }

    /**
     * 查询集合人脸
     * @param faceId
     * @param faceSetId
     * @return
     */
    @RequestMapping(value = "/user/info", method = RequestMethod.GET)
    public ResultVO findUserInfoFromSet(@RequestParam("faceId") String faceId, @RequestParam("faceSetId") String faceSetId) {
        if (NumberUtils.isDigits(faceId) && NumberUtils.isDigits(faceSetId)) {
            EcloudBaseResponseVO responseVO = faceService.findFaceMessageFromFaceSet(Integer.parseInt(faceId), Integer.parseInt(faceSetId));
            return responseToFront(responseVO);
        }
        else {
            return ResultVO.note(HttpStatus.FORBIDDEN.value(), "", "人脸集合或人员id类型不符");
        }
    }

    /**
     * 删除集合人员
     * @param request
     * @return
     */
    @RequestMapping(value = "/user/info", method = RequestMethod.DELETE)
    public ResultVO deleteUserInfoFromSet(@RequestBody Map<String, Integer> request) {
        int faceId = request.get("faceId");
        int faceSetId = request.get("faceSetId");
        EcloudBaseResponseVO responseVO = faceService.deleteFaceMessageFromFaceSet(faceId, faceSetId);
        return responseToFront(responseVO);
    }

    /**
     * 照片找集合中人员
     * @param closeNum
     * @param faceSetId
     * @param image
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "/person", method = RequestMethod.POST)
    public ResultVO searchUserFromImage(@RequestParam("closeNum") String closeNum, @RequestParam("faceSetId") String faceSetId, @RequestParam("img") MultipartFile image) throws IOException {
        if (NumberUtils.isDigits(closeNum) && NumberUtils.isDigits(faceSetId)) {
            EcloudBaseResponseVO responseVO = faceService.searchFaceInFaceSetFromImage(Integer.parseInt(closeNum), faceSetId, image);
            return responseToFront(responseVO);
        }
        else {
            return ResultVO.note(HttpStatus.FORBIDDEN.value(), "", "人脸集合或相似人员数量参数类型不符");
        }
    }

    /**
     * 照片找集合中人员并返回绘制图片
     * @param closeNum
     * @param faceSetId
     * @param image
     * @param response
     * @throws IOException
     */
    @PostMapping("/person/image")
    public void drawUserFromImage(@RequestParam("closeNum") String closeNum, @RequestParam("faceSetId") String faceSetId, @RequestParam("img") MultipartFile image, HttpServletResponse response) throws IOException {
        if (NumberUtils.isDigits(closeNum) && NumberUtils.isDigits(faceSetId)) {
            EcloudBaseResponseVO<File> responseVO = faceService.drawFaceInFaceSetFromImage(Integer.parseInt(closeNum), faceSetId, image);
            response.setContentType("image/jpeg");
            byte[] bytes = FileCopyUtils.copyToByteArray(responseVO.getBody());
            response.getOutputStream().write(bytes);
            response.getOutputStream().close();
            responseVO.getBody().delete();
        }
        else {
            response.setContentType(ContentType.APPLICATION_JSON.toString());
            response.getOutputStream().write(JSON.toJSONBytes(ResultVO.note(HttpStatus.FORBIDDEN.value(), "", "人脸集合或相似人员数量参数类型不符")));
        }
    }

    private ResultVO responseToFront(EcloudBaseResponseVO responseVO) {
        if (responseVO.getState().equals("OK")) {
            return ResultVO.success(responseVO.getBody());
        } else {
            return ResultVO.note(HttpStatus.INTERNAL_SERVER_ERROR.value(), "", responseVO.getErrorMessage());
        }
    }
}